package eclipse.lib.graphics;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.*;

import javax.media.opengl.*;
import com.sun.opengl.util.*;
/**
 *The GLInterface links the OpenGL object to the Application. It also handles keyboard events
 */
/*
 * Copyright (c) 2009, TOD Productions All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *	- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *	- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *	-Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
public final class GLInterface implements KeyListener
{
	private static final long serialVersionUID = 1L;
	//Object that all OpenGL Objects are drawn to
	private final GLCanvas glCanvas;
	//Thread that updates the OpenGL canvas
	private final Animator glAnimat;
	//Is the left key pressed?
	private boolean isLeft		= false;
	//Is the right key pressed?
	private boolean isRight		= false;
	//Is the up key pressed?
	private boolean isUp		= false;
	//Is the down key pressed?
	private boolean isDown		= false;
	//Is the tab key pressed?
	private boolean isTab		= false;	
	/**
	 * Creates the GLInterface with a specified surface and a OpenGL object
	 * @param dstSurface Surface to overwrite for OpenGL
	 * @param glObject OpenGL object
	 */
	public GLInterface(Container dstSurface, GLEventListener glObject)
	{
		//Build the OpenGL drawing surface
		glCanvas = new GLCanvas();				
		
		//Bind the renderer to the OpenGL canvas
		glCanvas.addGLEventListener(glObject);
		//Bind the key listener to the OpenGL canvas
		glCanvas.addKeyListener(this);
		//Bind the canvas to the animator
		glAnimat = new Animator(glCanvas);
		
		//Bind the canvas to the destination surface
		dstSurface.add(glCanvas);
		//Rebuild the destination surface
		dstSurface.validate();
		//Start OpenGL
		glAnimat.start();
	}	
	/**
	 * Creates the GLInterface with a specified surface, OpenGL object, and MouseListener
	 * @param dstSurface Surface to overwrite for OpenGL writing 
	 * @param glObject OpenGL object
	 * @param mListener Mouse Listener
	 */
	public GLInterface(Container dstSurface, GLEventListener glObject, MouseMotionListener mListener, MouseListener mListener2)
	{
		//Build the OpenGL drawing surface
		glCanvas = new GLCanvas();			
		
		//Bind the renderer to the Canvas
		glCanvas.addGLEventListener(glObject);
		//Bind the key listener to the Canvas
		glCanvas.addKeyListener(this);
		//Bind the Mouse Motion listener to the Canvas
		glCanvas.addMouseMotionListener(mListener);
		//Bind the Mouse Lister to the Canvas
		glCanvas.addMouseListener(mListener2);

		//Create a thread to update the Canvas
		glAnimat = new Animator(glCanvas);
		
		//bind the canvas to the destination surface
		dstSurface.add(glCanvas);
		//Rebuild the destination surface
		dstSurface.validate();
		//Start OpenGL thread
		glAnimat.start();	
	}
	//Runs if a key is pressed in the form.
	public final void keyPressed(KeyEvent e) 
	{				
		//check if console is to be opened
		//first check if c is pressed		
		if(e.getKeyCode() == KeyEvent.VK_F1)
		{			
			//send the command to the console, if eclipse.util.Boot is running, it will
			//pick this up as a command..
			System.out.println("-d show Opening console...");
		}	
		//Tab was pressed
		if(e.getKeyCode() == KeyEvent.VK_TAB)
		{
			//Set that tab was pressed
			isTab = true;			
		}
		//Up is pressed instead
		else if(e.getKeyCode() == KeyEvent.VK_UP)
		{
			//Check if down is still marked for being pressed 
			if(isDown)
			{
				//You cannot have both marked so remove the instance of down
				isDown	= false;
			}
			//Mark up as an instance of being pressed 
			isUp = true;
		}
		//Down is pressed instead
		else if(e.getKeyCode() == KeyEvent.VK_DOWN)
		{
			//Check if up is still marked for being pressed
			if(isUp)
			{
				//You cannot have both marked so remove the instance of up
				isUp = false;
			}
			//Mark down as an instance of being pressed
			isDown = true;
		}
		//Left is pressed instead 
		else if(e.getKeyCode() == KeyEvent.VK_LEFT)
		{
			//Check if right is still marked for being pressed
			if(isRight)			
			{
				//You cannot have both marked so remove the instance of Right
				isRight	= false;
			}
			//Mark left as an instance of being pressed
			isLeft			= true;
		}
		//Right is pressed instead
		else if(e.getKeyCode() == KeyEvent.VK_RIGHT)
		{
			//Check if left is still marked for being pressed
			if(isLeft)
			{
				//You cannot have both marked so remove the instance of Left
				isLeft = false;
			}
			//Mark right as an instance of being pressed
			isRight		= true;
		}			
	}
	
	//Runs when a key is stopped being pressed
	public final void keyReleased(KeyEvent e) 
	{		
		//Check if up is no longer being pressed
		if(e.getKeyCode() == KeyEvent.VK_UP)
		{
			//Mark up as not being pressed
			isUp = false;
		}
		//Check if down is no longer being pressed
		if(e.getKeyCode() == KeyEvent.VK_DOWN)
		{
			//Mark down as not being pressed
			isDown = false;
		}
		//Check if left is no longer being pressed
		if(e.getKeyCode() == KeyEvent.VK_LEFT)
		{
			//Mark left as not being pressed
			isLeft			= false;
		}
		//Check if right is no long er being pressed
		if(e.getKeyCode() == KeyEvent.VK_RIGHT)
		{
			//Mark right as not being pressed
			isRight			= false;		
		}
	}
	
	//Checks if a key is typed
	public final void keyTyped(KeyEvent e)
	{}
	
	/** Returns if right was pressed */
	public final boolean getRight()
	{
		//Return the value specified by the keystate of the Right arrow key
		return isRight;
	}
	/** Returns if left was pressed */
	public final boolean getLeft()
	{
		//Return the value specified by the keystate of the Left arrow key
		return isLeft;
	}
	/** Returns if up was pressed */
	public final boolean getUp()
	{
		//Return the value specified by the keystate of the Up arrow key
		return isUp;
	}
	/** Returns if down was pressed */
	public final boolean getDown()
	{
		//Return the value specified by the keystate of the Down arrow key
		return isDown;
	}
	/** Returns if tab was pressed */
	public final boolean getTab()
	{
		//Return the value specified by the keystate of the Tab key
		return isTab;
	}	
}